package com.ciei.dpagm.service.conditionRule;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ciei.dpagm.common.enums.*;
import com.ciei.dpagm.service.RuleSetService;
import com.ciei.dpagm.service.conditionRule.factMode.*;
import com.ciei.dpagm.service.conditionRule.standardSpecification.StandardSpecificationFactoryService;
import com.ciei.dpagm.util.APP;
import com.ciei.dpagm.util.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author pp
 * @date 2023/03/15
 */
@Service
public class ConditionHandleService {

    @Autowired
    private RuleSetService ruleSetService;

    @Autowired
    private FactModeFactoryService factModeFactoryService;

    @Autowired
    private StandardSpecificationFactoryService standardSpecificationFactoryService;

    @Autowired
    private CompareService compareService;

    private static String inconformitySystemNormTitle = "不符合系统的规范：";
    private static String notMatchDataTitle = "匹配不到系统的数据：";
    private static String notFoundDataTitle = "在系统找不到对应的数据：";
    private static String systemDataFillOutError = "系统数据填写有误：";
    private static String originDataNotFoundDataTitle = "在源数据找不到对应的数据：";



    /**
     * 评估
     * @param factModeStr 事实方式字符串
     * @param comparator 比较符
     * @param standardSpecificationStr 标准规范字符串
     * @param originData 源数据
     * @return
     */
    public JSONObject evaluate(String factModeStr, Integer comparator, String standardSpecificationStr, JSONObject originData){
        List<String> oldFactModeList = JSONObject.parseArray(factModeStr, String.class);
        List<String> oldStandardSpecificationList = JSONObject.parseArray(standardSpecificationStr, String.class);
        List<String> factModeList = conversionFactModeList(oldFactModeList);
        List<String> standardSpecificationList = conversionStandardSpecificationList(oldStandardSpecificationList);
        if(factModeList.isEmpty()){
            return ArraysSizeIsEmptyMessage(FactModeFactoryService.title);
        }
        if(standardSpecificationList.isEmpty()){
            return ArraysSizeIsEmptyMessage(StandardSpecificationFactoryService.title);
        }
        FactModeEnum lastLevelFactModeEnum = FactModeEnum.getEnumByValue(Integer.valueOf(factModeList.get(FactModeFactoryService.twoFactModeIndex)));
        if(lastLevelFactModeEnum == null){
            return notFoundCorrespondenceMessage(FactModeFactoryService.twoFactModeIndex,FactModeFactoryService.title);
        }
        JSONObject factModeToComparatorOptionListJson = ruleSetService.getFactModeToComparatorOptionList();
        if(!factModeToComparatorOptionListJson.getBoolean(APP.SUCCESS)){
            return factModeToComparatorOptionListJson;
        }
        JSONObject factModeToComparatorOptionListData = factModeToComparatorOptionListJson.getJSONObject(APP.DATA);
        JSONArray comparatorOptionList = factModeToComparatorOptionListData.getJSONArray(lastLevelFactModeEnum.getId().toString());
        Boolean isSupportComparator = false;
        for(int i = 0; i < comparatorOptionList.size();i++){
            JSONObject comparatorOptionData = comparatorOptionList.getJSONObject(i);
            Integer value = comparatorOptionData.getInteger("value");
            if(value.equals(comparator)){
                isSupportComparator = true;
            }
        }
        if(!isSupportComparator){
            return notMatchCompareMessage();
        }
        JSONObject factModeAndComparatorToStandardSpecificationOptionListJson = ruleSetService.getFactModeAndComparatorToStandardSpecificationOptionList(new ArrayList<>());
        if(!factModeAndComparatorToStandardSpecificationOptionListJson.getBoolean(APP.SUCCESS)){
            return factModeAndComparatorToStandardSpecificationOptionListJson;
        }
        JSONObject factModeAndComparatorToStandardSpecificationOptionListData = factModeAndComparatorToStandardSpecificationOptionListJson.getJSONObject(APP.DATA);
        JSONArray standardSpecificationOptionList = factModeAndComparatorToStandardSpecificationOptionListData.getJSONArray(lastLevelFactModeEnum.getId() + "-" + comparator);
        Boolean isSupportStandardSpecification = false;
        for(int i = 0;i < standardSpecificationOptionList.size();i++){
            // 解析一级
            JSONObject standardSpecificationOption = standardSpecificationOptionList.getJSONObject(i);
            if(!standardSpecificationList.get(0).equals(standardSpecificationOption.getInteger("value").toString())){
                continue;
            }
            if(ConditionalTypeEnum.STANDARD_SPECIFICATION.getId().equals(standardSpecificationOption.getInteger("type"))){
                if(standardSpecificationOption.getJSONArray("children") == null || standardSpecificationOption.getJSONArray("children").isEmpty()){
                    isSupportStandardSpecification = true;
                    break;
                }else{
                    if(ConditionalTypeEnum.STANDARD_SPECIFICATION.getId().equals(standardSpecificationOption.getJSONArray("children").getJSONObject(0).getInteger("type"))){
                        isSupportStandardSpecification = true;
                        break;
                    }
                }
            }
            JSONArray twoStandardSpecificationOptionList = standardSpecificationOption.getJSONArray("children");
            for(int twoStandardSpecificationIndex = 0; twoStandardSpecificationIndex < twoStandardSpecificationOptionList.size();twoStandardSpecificationIndex++){
                // 解析二级
                JSONObject twoStandardSpecificationOption = twoStandardSpecificationOptionList.getJSONObject(twoStandardSpecificationIndex);
                if(!standardSpecificationList.get(1).equals(twoStandardSpecificationOption.getInteger("value").toString())){
                    continue;
                }
                if(ConditionalTypeEnum.STANDARD_SPECIFICATION.getId().equals(twoStandardSpecificationOption.getInteger("type"))){
                    if(standardSpecificationOption.getJSONArray("children") == null || standardSpecificationOption.getJSONArray("children").isEmpty()){
                        isSupportStandardSpecification = true;
                        break;
                    }else{
                        if(ConditionalTypeEnum.STANDARD_SPECIFICATION.getId().equals(twoStandardSpecificationOption.getJSONArray("children").getJSONObject(0).getInteger("type"))){
                            isSupportStandardSpecification = true;
                            break;
                        }
                    }
                }
                JSONArray threeStandardSpecificationOptionList = twoStandardSpecificationOption.getJSONArray("children");
                for(int threeStandardSpecificationIndex = 0;threeStandardSpecificationIndex < threeStandardSpecificationOptionList.size();threeStandardSpecificationIndex++){
                    //解析三级
                    JSONObject threeStandardSpecificationOption = threeStandardSpecificationOptionList.getJSONObject(threeStandardSpecificationIndex);
                    if(standardSpecificationList.get(2).equals(threeStandardSpecificationOption.getInteger("value").toString())){
                        isSupportStandardSpecification = true;
                    }
                }
            }
        }
        if(!isSupportStandardSpecification){
            return notMatchStandardSpecificationMessage();
        }
        JSONObject factModeResultValueJson = factModeFactoryService.analysis(factModeList, originData);
        JSONObject standardSpecificationResultValueJson = standardSpecificationFactoryService.analysis(factModeList, comparator, standardSpecificationList,oldStandardSpecificationList);
        if(!factModeResultValueJson.getBoolean(APP.SUCCESS)){
            return factModeResultValueJson;
        }
        Object factModeResultValue = factModeResultValueJson.get(APP.DATA);
        if(!standardSpecificationResultValueJson.getBoolean(APP.SUCCESS)){
            return standardSpecificationResultValueJson;
        }
        Object standardSpecificationResultValue = standardSpecificationResultValueJson.get(APP.DATA);
        return compareService.compare(factModeResultValue,comparator,standardSpecificationResultValue);
    }

    /**
     * 转换下拉框列表
     * @param factModeStr 事实方式字符串
     * @param standardSpecificationStr 标准规范字符串
     * @param factModeOptionDataList 事实方式下拉框数据列表
     * @param standardSpecificationOptionDataList 标准规范下拉框数据列表
     */
    public void conversionOptionList(String factModeStr, String standardSpecificationStr,List<JSONObject> factModeOptionDataList,List<JSONObject> standardSpecificationOptionDataList){
        List<String> oldFactModeList = JSONObject.parseArray(factModeStr, String.class);
        List<String> oldStandardSpecificationList = JSONObject.parseArray(standardSpecificationStr, String.class);
        List<String> factModeList = conversionFactModeList(oldFactModeList);
        List<String> standardSpecificationList = conversionStandardSpecificationList(oldStandardSpecificationList);
        if(factModeList.isEmpty()){
            return;
        }
        if(standardSpecificationList.isEmpty()){
            return;
        }
        StandardSpecificationEnum standardSpecificationEnum = StandardSpecificationEnum.getEnumByValue(Integer.valueOf(standardSpecificationList.get(0)));
        if(standardSpecificationEnum == null){
            return;
        }
        List<JSONObject> sonStandardSpecificationOptionDataList = new ArrayList<>();
        standardSpecificationFactoryService.conversionOptionList(standardSpecificationList,sonStandardSpecificationOptionDataList);
        JSONObject standardSpecificationOptionData = new JSONObject();
        standardSpecificationOptionData.fluentPut("value",standardSpecificationEnum.getId())
                .fluentPut("label",standardSpecificationEnum.getName());
        if(!sonStandardSpecificationOptionDataList.isEmpty()){
            standardSpecificationOptionData.fluentPut("children",sonStandardSpecificationOptionDataList);
        }
        standardSpecificationOptionDataList.add(standardSpecificationOptionData);

        FactModeEnum factModeEnum = FactModeEnum.getEnumByValue(Integer.valueOf(factModeList.get(FactModeFactoryService.oneFactModeIndex)));
        if(factModeEnum == null){
            return;
        }
        FactModeEnum twoFactModeEnum = FactModeEnum.getEnumByValue(Integer.valueOf(factModeList.get(FactModeFactoryService.twoFactModeIndex)));
        if(twoFactModeEnum == null){
            return;
        }
        List<JSONObject> sonFactModeOptionDataList = new ArrayList<>();
        factModeFactoryService.conversionOptionList(factModeList,sonFactModeOptionDataList,twoFactModeEnum);
        List<JSONObject> twoFactModeOptionDataList = new ArrayList<>();
        JSONObject twoFactModeOptionData = new JSONObject();
        twoFactModeOptionData.fluentPut("value",twoFactModeEnum.getId())
                .fluentPut("label",twoFactModeEnum.getName())
                .fluentPut("children",sonFactModeOptionDataList);
        twoFactModeOptionDataList.add(twoFactModeOptionData);
        JSONObject factModeOptionData = new JSONObject();
        factModeOptionData.fluentPut("value",factModeEnum.getId())
                .fluentPut("label",factModeEnum.getName())
                .fluentPut("children",twoFactModeOptionDataList);
        factModeOptionDataList.add(factModeOptionData);
    }

    /**
     * 转换事实方式列表
     * @param oldFactModeList
     * @return
     */
    public List<String> conversionFactModeList(List<String> oldFactModeList){
        List<String> factModeList = new ArrayList<>();
        oldFactModeList.forEach(f -> {
            if(f.contains(RuleSetService.optionValueSeparator)){
                Integer valueIndex = f.lastIndexOf(RuleSetService.optionValueSeparator) + RuleSetService.optionValueSeparator.length();
                factModeList.add(f.substring(valueIndex));
            }else{
                factModeList.add(f);
            }
        });
        return factModeList;
    }

    /**
     * 转换标准规范列表
     * @param oldStandardSpecificationList
     * @return
     */
    public List<String> conversionStandardSpecificationList(List<String> oldStandardSpecificationList){
        List<String> standardSpecificationList = new ArrayList<>();
        oldStandardSpecificationList.forEach(s -> {
            if(s.contains(RuleSetService.optionValueSeparator)){
                Integer valueIndex = s.lastIndexOf(RuleSetService.optionValueSeparator) + RuleSetService.optionValueSeparator.length();
                standardSpecificationList.add(s.substring(valueIndex));
            }else{
                standardSpecificationList.add(s);
            }
        });
        return standardSpecificationList;
    }

    /**
     * 数组(事实方式、标准规范)为空的消息
     * @param title
     * @return
     */
    public static JSONObject ArraysSizeIsEmptyMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY, inconformitySystemNormTitle + title + "数组为空");
    }

    /**
     * 找不到对应关系的消息
     * @param index
     * @param title
     * @return
     */
    public static JSONObject notFoundCorrespondenceMessage(Integer index, String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND, inconformitySystemNormTitle + "第" + (index + 1 ) + "级" + title + "跟当前关系结构对应不上");
    }

    /**
     * 匹配不到解析的消息
     * @param index
     * @param title
     * @return
     */
    public static JSONObject notMatchAnalyzeMessage(Integer index, String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,notMatchDataTitle + "第" + (index + 1) + "级" + title + "在系统匹配不到对应的解析");
    }

    /**
     * 匹配不到解析的消息
     * @param title
     * @return
     */
    public static JSONObject notMatchAnalyzeMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,notMatchDataTitle + title + "在系统匹配不到对应的解析");
    }

    /**
     * 数组大小不匹配
     * @param title
     * @return
     */
    public static JSONObject ArraySizeNotMatchMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.INVALID_PARAM, inconformitySystemNormTitle + title + "的定义和系统支持的数组大小不匹配");
    }

    /**
     * 找不到变量模块数据消息
     * @param title
     * @return
     */
    public static JSONObject notFoundParameterModuleDataMessage(String title){
        return notFoundDataMessage(title,"变量模块");
    }

    /**
     * 找不到变量数据消息
     * @param title
     * @return
     */
    public static JSONObject notFoundParameterDataMessage(String title){
        return notFoundDataMessage(title,"变量");
    }

    /**
     * 变量模块key为null消息
     * @param title
     * @return
     */
    public static JSONObject parameterModuleKeyIsNullMessage(String title){
        return keyIsNullMessage(title,"变量模块");

    }

    /**
     * 变量key为null消息
     * @param title
     * @return
     */
    public static JSONObject parameterKeyIsNullMessage(String title){
        return keyIsNullMessage(title,"变量");
    }

    /**
     * 在源数据找不到变量模块数据消息
     * @param title
     * @return
     */
    public static JSONObject originDataNotFoundParameterModuleDataMessage(String title){
        return originDataNotFoundDataMessage(title,"变量模块");
    }

    /**
     * 在源数据找不到变量数据消息
     * @param title
     * @return
     */
    public static JSONObject originDataNotFoundParameterDataMessage(String title){
        return originDataNotFoundDataMessage(title,"变量");
    }

    /**
     * 匹配不到比较符消息
     * @return
     */
    public static JSONObject notMatchCompareMessage(){
        return notMatchDataMessage(CompareService.title);
    }

    /**
     * 匹配不到标准规范消息
     * @return
     */
    public static JSONObject notMatchStandardSpecificationMessage(){
        return notMatchDataMessage(StandardSpecificationFactoryService.title);
    }

    /**
     * 匹配不到子类消息
     * @param title
     * @return
     */
    public static JSONObject notMatchSonServiceMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,notMatchDataTitle + "匹配不到对应的" + title + "子类");
    }

    /**
     * 变量数据类型为null消息
     * @param title
     * @return
     */
    public static JSONObject parameterDataTypeIsNullMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,systemDataFillOutError + "系统定义的" + title + "变量数据类型为null");
    }

    /**
     * 不支持该数据类型
     * @return
     */
    public static JSONObject notSupportDataTypeMessage(){
        return notSupportMessage("数据类型");
    }

    /**
     * 不支持该标准规范
     * @return
     */
    public static JSONObject notSupportStandardSpecificationMessage(){
        return notSupportMessage(StandardSpecificationFactoryService.title);
    }

    /**
     * 不支持该比较符
     * @return
     */
    public static JSONObject notSupportComparatorMessage(){
        return notSupportMessage(CompareService.title);
    }

    /**
     * 不支持
     * @return
     */
    public static JSONObject notSupportMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_OPERATION_DENY,inconformitySystemNormTitle + "不支持该" + title);
    }


    /**
     * 找不到数据消息
     * @param title
     * @param type
     * @return
     */
    private static JSONObject notFoundDataMessage(String title, String type){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,notFoundDataTitle + "找不到对应的" + title + type + "数据");
    }

    /**
     * 匹配不到数据消息
     * @param title
     * @return
     */
    private static JSONObject notMatchDataMessage(String title){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,notMatchDataTitle + "匹配不到对应的" + title + "数据");
    }

    /**
     * key为null消息
     * @param title
     * @param type
     * @return
     */
    private static JSONObject keyIsNullMessage(String title,String type){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,systemDataFillOutError + "系统定义的" + title + type + "key为null");
    }

    /**
     * 在源数据找不到对应的数据消息
     * @param title
     * @return
     */
    public static JSONObject originDataNotFoundDataMessage(String title,String type){
        return JsonUtil.getFail(ErrorCodeEnum.DATA_NOT_FOUND,originDataNotFoundDataTitle + "通过" + title + "定义的" + type + "key在源数据找不到对应的数据");
    }


}
